const { timeOptions } = require('../configs/OPTIONS')
const { getLabelByValue } = require('../utils/util')

const WindToIndex = {
  east: 1,
  south: 2,
  west: 3,
  north: 4
}

/**
 * 比较场风A和B的先后顺序，A在前返回值-1，相同返回0，A在后返回1
 * @param {string} windA 场风A
 * @param {string} windB 场风B
 */
export function compareSceneWinds(windA, windB) {
  if (windA === windB) {
    return 0
  }
  const indexA = WindToIndex[windA]
  const indexB = WindToIndex[windB]
  return indexA > indexB ? 1 : -1
}

/**
 * 获取一局数据插入到一组数据中的索引
 * @param {Array} records 一组对局数据
 * @param {object} record 一局对局数据
 */
function getInsertIndex(records, record) {
  const findIndex = records.findIndex(r => {
    const compareWindRes = compareSceneWinds(r.wind, record.wind);
    if (compareWindRes === 1) {
      return true
    } else if (compareWindRes === 0) {
      if (r.round > record.round) {
        return true
      } else if (r.round === record.round) {
        return r.byte > record.byte;
      }
    }
    return false;
  })
  return findIndex === -1 ? records.length : findIndex;
}

function getWindText(wind) {
  return { east: '东', south: '南', west: '西', 'north': '北' }[wind]
}

function getRoundText(round) {
  return ' 一二三四'[round];
}

function getByteText(byte) {
  return byte === 0 ? '' : byte + '本场'
}

function getRoundInfo(record) {
  return getWindText(record.wind) + getRoundText(record.round) + '局' + getByteText(record.byte)
}

function getTimeMarkInfo(record) {
  const { time, mark } = record;
  const timeText = getLabelByValue(timeOptions, time)
  return timeText + mark + '符';
}

function getNextWind(wind) {
  if (wind === 'east') {
    return 'south'
  } else if (wind === 'south') {
    return 'west'
  } else if (wind === 'west') {
    return 'north'
  }
  return ''
}

/**
 * 获取下一局信息，包含wind、round、byte
 * @param {Object} record 一局信息
 */
function getNextRecord(record) {
  if (!record) {
    return { wind: 'east', round: 1, byte: 0 }
  }
  const { result, winGamer, round, tingGamers, wind, byte } = record;
  const nextRecord = {}
  // 判断下一局是否连庄
  // 庄家和牌 或 流局时庄家听牌
  if ((result === 'hu' && round - 1 === winGamer) || (result === 'liu' && tingGamers.includes(round - 1))) {
    Object.assign(nextRecord, { wind, round, byte: byte + 1 })
  }
  else {
    // 不连庄有两种情况，流局庄家未听牌 与 子家胡牌
    // 当流局庄家未听牌时，本场数应+1
    // 流局时庄家未听牌，到下一轮时本场数要+1
    const nextByte = result === 'liu' ? byte + 1 : 0;
    if (round === 4) {
      Object.assign(nextRecord, { wind: getNextWind(wind), round: 1, byte: nextByte })
    } else {
      Object.assign(nextRecord, { wind, round: round + 1, byte: nextByte })
    }
  }
  return nextRecord;
}

/**
 * 获取一组对局数据的剩余立直点棒数
 * @param {Array} records 一组对局数据
 */
function getLeftStickNumOfRecords(records) {
  let lastIndex = records.length - 1;
  let stickNum = 0;
  while (lastIndex >= 0) {
    const { result, reachGamers } = records[lastIndex];
    if (result === 'liu') {
      if (Array.isArray(reachGamers)) {
        stickNum += reachGamers.length;
      }
    } else {
      return stickNum;
    }
    lastIndex--;
  }
  return stickNum;
}

module.exports = { getInsertIndex, getRoundInfo, getTimeMarkInfo, getNextRecord, getLeftStickNumOfRecords }